home *** CD-ROM | disk | FTP | other *** search
/ PCMania 64 / PCMania CD64_1.iso / phy / phy006 / phylez! / articulo.t10 < prev    next >
Encoding:
Text File  |  1997-02-07  |  9.7 KB  |  1 lines

  1. ε                      OPTIMIZACION EN ASSEMBLER (III)                               ε                      -------------------------------                                                                                                                                                                                                                 Todos los que tienen un grado avanzado de conocimientos de ensamblador       y procesos internos del procesador, saben que hay ciertas instrucciones que          por su cálculo interno y todo eso, son bastante lentas. Entre ellas están las        instrucciones δMULπ, δDIVπ, etc. Vamos a verlas una por una:                                                                                                              φ MULπ                                                                                                                                                                            La instrucción δMULπ es fácilmente emulable, y llamarla directamente es      bastante lento. En ciertos casos, nos convendrá sustituirla por un grupo de          instrucciones que irán más rápidas en su conjunto que a la hora de hacer δMULπ.      Estos casos son, por ejemplo, a la hora de multiplicar por una potencia de 2.        La manera:                                                                                                                                                                Γ                        MOV     AX, 1234h                                           Γ                        MOV     CX, 0002                                            Γ                        MUL     AX                                                                                                                                       gasta mucho procesador y va despacio, gastando bastantes tics de reloj del pro-      cesador. Otra manera de hacer esto mismo mucho más rápido es:                                                                                                             Γ                        MOV     AX, 1234h                                           Γ                        SHL     AX, 1                                                                                                                                            Recordemos que las operaciones a nivel de bits son siempre muy rápidas,      y para multiplicar por las potencias de dos (siempre que no rebasemos el re-         gistro) podemos utilizar desplazamiento de bits a la izquierda.                                                                                                                   Un ejemplo muy bueno de esta práctica es la rutina (ya casi un standard      de la programación gráfica) ΩPonPixelπ. En una resolución 320x200x256 (VGA modo      13h, el de la mayoría de los juegos de ordenador), para poner un pixel del           color CL en la posición en pantalla BX,DX habrá que aplicar la siguiente fór-        mula:                                                                                                                                                                     Γ                PosicionMemo = PosY * 320 + PosX                                    Γ                A000:[PosicionMemo] = Color                                                                                                                                      Esto, aplicado a ensamblador, nos daría que hay que multiplicar DX por       320 y sumarle BX, y después mover en la posición de memoria que nos ha dado la       formulita el registro CL. Pero lo que no vamos a hacer es multiplicar por 320        porque a la hora de repetir muchas veces la llamada a la rutina, esto se tra-        duce en una pérdida de velocidad alarmante. Entonces echamos mano de la ventaja      de los desplazamientos de bits:                                                                                                                                           φES=A000h, CL=Color, BX=PosX, DX=PosY                                                                                                                                     Σ        No optimizado                   Optimizado                                  Σ        -------------                   ----------                                  Γ        MOV     AX, 0320d               ROR     DX, 8                               Γ        MUL     DX                      ADD     BX, DX                              Γ        ADD     BX, DX                  ROR     DX, 2                               Γ        MOV     ES:[BX], CL             ADD     BX, DX                              Γ                                        MOV     ES:[BX], CL                                                                                                                      En la primera rutina aplicamos la instrucción δMULπ, que es la lenta. En     la optimizada, nos encontramos con dos desplazamientos de bits y dos sumas, que      en realidad es muchísimo más rápido que la instrucción δMULπ. Repasemos la segun-    da rutina paso a paso:                                                                                                                                                    ∩1) Multiplica DX por 256 π(desplazamiento de 8 bits a la izquierda)                 ∩2) Suma a BX el valor obtenido                                                      ∩3) Multiplica DX por 64π (desplaza 2 bits a la derecha, pero como si hubiera                                 desplazado 6 bits a la izquierda el DX inicial).            ∩4) Suma a BX el valor obtenido                                                      ∩5) Pone el color en la memoria de vídeo                                                                                                                                          Para hacer esto, hemos echado mano de las matemáticas y de la propie-        dad distributiva: δY*320+X = Y*(256+64)+X = Y*256+Y*64+X                                                                                                                          Entonces, para optimizar una multiplicación tenemos que repartir la          constante que multiplica en potencias de dos, y utilizar desplazamientos de          bits. Pero siempre sin pasarse, claro. Si hay que hacer 5 o 6 desplazamientos        con sus respectivas sumas, conviene utilizar δMULπ.                                                                                                                               Por cierto, no hay que olvidar que estas maneras son flexibles, y no         hay por qué usar siempre sumas. Si tuviéramos que multiplicar un número por          63 sería lo mismo que multiplicarlo por 64 y restarle el número inicial. Hay         que encontrar una manera de hacerlo más rápido, y la suma es tan rápida como         la resta.                                                                                                                                                                 φ DIV                                                                                                                                                                             Para dividir, es bastante más restringido el tema, porque sólo se pue-       den aplicar los desplazamientos de bits cuando se divide entre potencias de          dos, y siempre teniendo en cuenta de que si se utilizan no tendremos acceso al       resto. Pero en casos como hacer medias, y todo eso, los desplazamientos están        "bien vistos".                                                                                                                                                            φ LOOP                                                                                                                                                                            Al menos hasta el Pentium, la instrucción δLOOPπ es más lenta que usar       el par δDEC CX/JNZ ...π , y como normalmente no programamos sólo para Pentium,       es recomendable usar esto último. Además, tiene la ventaja de que podemos usar       cualquier registro como contador, no sólo CX. Entonces, un algoritmo de repeti-      ción será más rápido de esta manera:                                                                                                                                      Σ        Manera "lenta"                  Manera "rápida"                             Σ        --------------                  ---------------                                                                                                                  Γ        ...         π; Algoritmo   Γ      ...         π; Algoritmo                  Γ        LOOP    InicioAlgoritmo         DEC     CX                                  Γ                                        JNZ     InicioAlgoritmo                                                                                                                  Con esto arañaremos un ciclo de reloj al algoritmo en procesadores in-       feriores al Pentium, que nos servirá de mucho en procesos en los que tengamos        que llamar a la rutina muchas veces.                                                                                                                                                                                                                                   Y éstas son las más importantes. Sólo hay que recordar que las opera-        ciones a nivel de bits son las más rápidas, y siempre que podamos traducir un        proceso sólo (o en su mayoría) a operaciones con bits habremos ganado en velo-       cidad. Hasta el próximo número.                                                                                                                                                                                           ∞Líyak el Oscuroπ